/*
 * @Author: Drc
 * @Date: 2020-06-11 14:43:22
 * @LastEditors: Drc
 * @LastEditTime: 2021-11-04 14:43:41
 */

import i18n from 'i18n-js'
import {getLocales, Locale as LocaleType} from 'react-native-localize'
import {string_zh, string_en, image_zh, image_en, color_zh, color_en, string_plain, string_param} from './index'
import AsyncStorage from '@react-native-community/async-storage'
import store from '@path/redux'
import {Text} from 'react-native'

export type supportLocale = 'zh' | 'en'
type resourceType = 'string' | 'image' | 'color'
const LOCALE_STORAGE_KEY = 'LOCALE_STORAGE_KEY'
export const DEFAULT_LANGUAGE = 'zh'

/**
 * 国际化资源操作类
 */
export default class Locale {
  static currentLocale: supportLocale = DEFAULT_LANGUAGE

  /**
   * 初始化
   * @param fallback 未命中语言时是否允许往下尝试
   * @param defaultLocale 默认语言
   */
  static init(defaultLocale?: supportLocale): Promise<any> {
    i18n.translations = {
      zh: {string_zh, image_zh, color_zh},
      en: {string_en, image_en, color_en},
    }
    i18n.fallbacks = true

    return new Promise((resolve) => {
      if (defaultLocale) {
        i18n.defaultLocale = this.currentLocale = defaultLocale
        resolve(null)
      } else {
        this.getLocale()
          .then((locale) => {
            i18n.defaultLocale = this.currentLocale = locale
            resolve(null)
          })
          .catch(() => {
            i18n.defaultLocale = this.currentLocale = this._handleLocale(getLocales())
            resolve(null)
          })
      }
    })
  }

  /**
   * 使用国际化字符串
   * @param key 资源key
   * @param type 资源类型，默认为string
   */
  static getString<T extends keyof typeof string_plain>(key: T, param: string_param[T] = {}): typeof string_plain[T] {
    return this.use(key, 'string', param)
  }

  /**
   * 使用国际化图片
   * @param key 资源key
   * @param type 资源类型，默认为image
   */
  static getImage<T extends keyof typeof image_zh>(key: T): typeof image_zh[T] {
    return this.use(key, 'image')
  }

  /**
   * 使用国际化图片
   * @param key 资源key
   * @param type 资源类型，默认为color
   */
  static getColor<T extends keyof typeof color_zh>(key: T): typeof color_zh[T] {
    return this.use(key, 'color')
  }

  /**
   * 使用国际化内容
   * @param key 资源key
   * @param type 资源类型
   */
  static use<T extends keyof typeof string_plain, S extends keyof typeof image_zh, U extends keyof typeof color_zh>(
    key: T | S | U,
    type: resourceType,
    param: any = {},
  ): any {
    return i18n.t(`${type}_${this.currentLocale}.${key}`, param)
  }

  /**
   * 改变语言
   * @param locale 语言
   */
  static setLocale(locale: supportLocale): Promise<any> {
    return new Promise((resolve, reject) => {
      if (this.currentLocale === locale) {
        resolve(this.currentLocale)
        return
      }
      AsyncStorage.setItem(LOCALE_STORAGE_KEY, locale)
        .then(() => {
          this.currentLocale = locale
          i18n.defaultLocale = locale
          store.dispatch.global.setLocale(locale)
          resolve(locale)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  //从持久化获取默认语言
  static getLocale(): Promise<any> {
    return new Promise((resolve, reject) => {
      AsyncStorage.getItem(LOCALE_STORAGE_KEY)
        .then((locale) => {
          if (!locale) {
            reject()
            return
          }
          resolve(locale)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  //将原生获取到的语言 -> i18n语言
  static _handleLocale(languages: LocaleType[]): string {
    if (Array.isArray(languages) && languages.length > 0) {
      let result = languages[0]?.languageCode
      return Object.keys(result).includes(result) ? result : DEFAULT_LANGUAGE
    } else {
      return DEFAULT_LANGUAGE
    }
  }

  //设置字体
  static _handleFont(locale: supportLocale) {
    const _getFontFamily = () => {
      switch (locale) {
        case 'zh':
        case 'en':
        default:
          return undefined
      }
    }

    const originTextRender = Text.render
    Text.render = function render(props, ref) {
      return originTextRender.apply(this, [
        {
          ...props,
          style: [{fontFamily: _getFontFamily()}, props.style],
          allowFontScaling: false,
        },
        ref,
      ])
    }
  }

  /**
   * 获取冒号
   */
  static getColon(locale: supportLocale = this.currentLocale) {
    switch (locale) {
      case 'zh':
        return '：'
      case 'en':
        return ':'
      default:
        break
    }
  }
}
